# -*- coding: utf-8 -*-
import os
import json
import sys

from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.Qt import *
from PyQt5.QtGui import *
from PyQt5 import QtMultimedia
from client.pages.UserMainWin import *
from client.pages.UserFriendWin import *
from client.pages.UserGroupWin import *
from client.pages.UserMeWin import *
from client.pages.UserSearchWin import *
from client.pages.NewFriendPage import *
from client.pages.ChangePswdPage import *
from client.pages.FriendInfoPage import *
from client.pages.GroupInfoPage import *
from client.pages.InfoPage import InfoPage
from client.pages.MyPart import ListItem
from client.func.ClientHttp import *
from client.func.ImgOperate import compress_image

import client.pages.global_win as gw

root = "./"
img_dir = "client/.cache/img_buf/"


class UpdateThread(QThread):
    update_signal = pyqtSignal()
    net_signal = pyqtSignal(str)
    remote_landing_signal = pyqtSignal()

    def __init__(self):
        super(UpdateThread, self).__init__()
        self.uid = ""
        self.loudness = self.load_config()  # 声音大小
        file = QUrl.fromLocalFile('./client/src/qq.wav')  # 音频文件路径
        content = QtMultimedia.QMediaContent(file)
        self.player = QtMultimedia.QMediaPlayer()
        self.player.setMedia(content)
        self.player.setVolume(self.loudness)

    def load_config(self):
        config_path = "client/.cache/config.json"
        if os.path.exists(config_path):
            try:
                with open(config_path, "r") as f:
                    return json.load(f)["sound"]
            except Exception as e:
                print("load_config:", e)
                return 50
        else:
            return 50

    def save_config(self):
        config_path = "client/.cache/config.json"
        if os.path.exists(config_path):
            try:
                with open(config_path, "r") as f:
                    dic = json.load(f)
                dic["sound"] = self.loudness
                with open(config_path, "w") as f:
                    f.write(json.dumps(dic))
            except Exception as e:
                print("save_config:", e)
        else:
            dic = {
                "User": {}, "sound": self.loudness
            }
            with open(config_path, "w") as f:
                f.write(json.dumps(dic))

    def run(self):
        while True:
            net, remote_landing, update_flag, sound_flag = get_update_post(self.uid)
            if net:
                self.net_signal.emit(u"有网络")
            else:
                self.net_signal.emit(u"无网络")
            if remote_landing:
                self.remote_landing_signal.emit()
            if update_flag:
                self.update_signal.emit()
            if sound_flag:
                self.player.play()
                time.sleep(2)
            time.sleep(1)

    def change_loudness(self, loudness: int):
        self.loudness = loudness
        self.player.setVolume(self.loudness)
        self.player.play()
        time.sleep(2)
        self.save_config()


class UserSearchPage(QWidget, Ui_UserSearchWin):
    def __init__(self):
        super(UserSearchPage, self).__init__()
        self.setupUi(self)
        self.myuid = ""
        self.mode = "user"
        self.user_dicts = []
        self.group_dicts = []
        self.user_list = []
        self.group_list = []
        self.find_friend_button.clicked.connect(lambda: self.OnChangeMode(self.find_friend_button.objectName()))
        self.find_group_button.clicked.connect(lambda: self.OnChangeMode(self.find_group_button.objectName()))
        self.listWidget.itemClicked.connect(self.OnItemClicked)

    def OnItemClicked(self, item):
        uid = item.uid
        if item.category == "friend":
            if "u"+uid not in gw.get_keys():
                win = FriendInfoPage()
                win.uid = uid
                win.myuid = self.myuid
                gw.set_value("u"+uid, win)
                win.update()
                win.show()
            else:
                gw.get_value("u" + uid).update()
                gw.get_value("u" + uid).show()
        else:
            if "g"+uid not in gw.get_keys():
                win = GroupInfoPage()
                win.myuid = self.myuid
                win.uid = uid
                gw.set_value("g" + uid, win)
                win.update()
                win.show()
            else:
                gw.get_value("g" + uid).update()
                gw.get_value("g" + uid).show()

    def OnChangeMode(self, name):
        if name == "find_friend_button":
            self.mode = "user"
        else:
            self.mode = "group"
        self.update()

    def clear(self):
        self.user_list.clear()
        self.group_list.clear()
        self.listWidget.clear()

    def update(self):
        self.clear()
        if self.mode == "user":
            for dic in self.user_dicts:
                item = ListItem()
                item.name = dic["name"]
                item.uid = dic["uid"]
                item.new_msg = dic["uid"]
                item.category = "friend"
                item.img_path = root + img_dir + dic["img"]
                item.set_img(item.img_path)
                item.update()
                self.user_list.append(item)
                self.listWidget.addItem(item)
                self.listWidget.setItemWidget(item, item.widget)
        else:
            for dic in self.group_dicts:
                item = ListItem()
                item.name = dic["name"]
                item.uid = dic["uid"]
                item.new_msg = dic["uid"]
                item.category = "group"
                item.img_path = root + img_dir + dic["img"]
                item.set_img(item.img_path)
                item.update()
                self.group_list.append(item)
                self.listWidget.addItem(item)
                self.listWidget.setItemWidget(item, item.widget)


class UserFriendPage(QWidget, Ui_UserFriendWin):
    msg_num_signal = pyqtSignal()

    def __init__(self):
        super(UserFriendPage, self).__init__()
        self.setupUi(self)
        self.myuid = ""
        self.setWindowFlags(Qt.FramelessWindowHint)
        self.friend_dicts = []
        self.friend_list = []
        self.search_list = []
        self.search_flag = False

        self.search_button.clicked.connect(self.OnSearch)
        self.search_text.editingFinished.connect(self.CancelSearch)
        self.listWidget.itemClicked.connect(self.OnItemClicked)

    def OnItemClicked(self, item):
        uid = item.uid
        item.msg_num = 0
        item.msg_num_update()
        self.msg_num_signal.emit()
        if item.category == "friend":
            if "u" + uid not in gw.get_keys():
                win = FriendInfoPage()
                win.uid = uid
                win.myuid = self.myuid
                gw.set_value("u" + uid, win)
                win.update()
                win.show()
            else:
                gw.get_value("u" + uid).update()
                gw.get_value("u" + uid).show()
        change_msg_info_num_post(self.myuid, uid, "friend", 0)

    def update(self):
        if not self.search_flag:
            self.clear_list()
            self.get_friend_list(self.friend_dicts)
            self.update_items()
            self.import_friend(self.friend_list)

    def clear_list(self):
        self.friend_list.clear()
        self.search_list.clear()
        self.listWidget.clear()

    def update_items(self):
        for item in self.friend_list:
            item.update()

    def calc_msg_num(self):
        return sum([item.msg_num for item in self.friend_list])

    def clear_all_msg_num(self):
        for dic in self.friend_dicts:
            dic["msg_num"] = 0
            change_msg_info_num_post(self.myuid, dic["uid"], "friend", 0)
        self.update()

    def get_friend_list(self, dict_list):
        for dic in dict_list:
            item = ListItem()
            item.name = dic["name"]
            item.uid = dic["uid"]
            item.new_msg = dic["new_msg"]
            item.msg_num = dic["msg_num"]
            item.category = "friend"
            item.img_path = root + img_dir + dic["img"]
            item.set_img(item.img_path)
            item.update()
            self.friend_list.append(item)

    def import_friend(self, item_list: list):
        for item in item_list:
            self.listWidget.addItem(item)
            self.listWidget.setItemWidget(item, item.widget)

    def get_search_list(self, name: str):
        for item in self.friend_list:
            if name in item.name or name in item.uid:
                self.search_list.append(item)

    def OnSearch(self):
        self.search_flag = True
        self.clear_list()
        self.get_friend_list(self.friend_dicts)
        search_name = self.search_text.text()
        self.get_search_list(search_name)
        self.import_friend(self.search_list)

    def CancelSearch(self):
        self.search_flag = False
        if not self.search_text.text():
            self.update()


class UserGroupPage(QWidget, Ui_UserGroupWin):
    msg_num_signal = pyqtSignal()

    def __init__(self):
        super(UserGroupPage, self).__init__()
        self.setupUi(self)
        self.setWindowFlags(Qt.FramelessWindowHint)
        self.myuid = ""
        self.group_dicts = []
        self.group_list = []
        self.search_list = []
        self.search_flag = False

        self.search_button.clicked.connect(self.OnSearch)
        self.search_text.editingFinished.connect(self.CancelSearch)
        self.listWidget.itemClicked.connect(self.OnItemClicked)

    def OnItemClicked(self, item):
        try:
            uid = item.uid
            item.msg_num = 0
            item.msg_num_update()
            self.msg_num_signal.emit()
            if item.category == "group":
                if "g" + uid not in gw.get_keys():
                    win = GroupInfoPage()
                    win.myuid = self.myuid
                    win.uid = uid
                    gw.set_value("g" + uid, win)
                    win.update()
                    win.show()
                else:
                    gw.get_value("g" + uid).update()
                    gw.get_value("g" + uid).show()
            change_msg_info_num_post(self.myuid, uid, "group", 0)
        except Exception as e:
            print(e)

    def update(self):
        if not self.search_flag:
            self.clear_list()
            self.get_group_list(self.group_dicts)
            self.update_items()
            self.import_group(self.group_list)

    def clear_list(self):
        self.group_list.clear()
        self.search_list.clear()
        self.listWidget.clear()

    def update_items(self):
        for item in self.group_list:
            item.update()

    def calc_msg_num(self):
        return sum([item.msg_num for item in self.group_list])

    def clear_all_msg_num(self):
        for dic in self.group_dicts:
            dic["msg_num"] = 0
            change_msg_info_num_post(self.myuid, dic["uid"], "group", 0)  # 清除列表群聊消息
        self.update()

    def get_group_list(self, dict_list):
        for dic in dict_list:
            item = ListItem()
            item.name = dic["name"]
            item.uid = dic["uid"]
            item.new_msg = dic["new_msg"]
            item.msg_num = dic["msg_num"]
            item.category = "group"
            item.img_path = root + img_dir + dic["img"]
            item.set_img(item.img_path)
            item.update()
            self.group_list.append(item)

    def import_group(self, item_list: list):
        for item in item_list:
            self.listWidget.addItem(item)
            self.listWidget.setItemWidget(item, item.widget)

    def get_search_list(self, name: str):
        for item in self.group_list:
            if name in item.name or name in item.uid:
                self.search_list.append(item)

    def OnSearch(self):
        self.search_flag = True
        self.clear_list()
        self.get_group_list(self.group_dicts)
        search_name = self.search_text.text()
        self.get_search_list(search_name)
        self.import_group(self.search_list)

    def CancelSearch(self):
        self.search_flag = False
        if not self.search_text.text():
            self.update()


class UserMePage(QWidget, Ui_UserMeWin):
    def __init__(self):
        super(UserMePage, self).__init__()
        self.setupUi(self)
        self.setWindowFlags(Qt.FramelessWindowHint)
        self.init_status = False
        self.explain = ""
        self.name = u"昵称"
        self.img_path = root+img_dir+"user_default.png"
        self.sex = "boy"
        self.search_accept = True
        self.uid = ""

        self.pswd_win = ChangePswdPage()

        self.name_edit_button.clicked.connect(self.OnEditName)
        self.name_edit.editingFinished.connect(self.OnEditNameFinished)
        self.change_img_button.clicked.connect(self.OnChangeImg)
        self.save_button.clicked.connect(self.OnSaveChange)
        self.pswd_button.clicked.connect(self.OnPswd)

    def OnPswd(self):
        self.pswd_win.uid = self.uid
        self.pswd_win.show()

    def OnSaveChange(self):
        info = {
            "name": self.name,
            "sex": self.get_check_box(),
            "img_path": self.img_path,
            "search_accept": self.can_search.isChecked(),
            "explain": self.explainEdit.toPlainText()
        }
        status = change_user_info_post(self.uid, info)

    def OnChangeImg(self):
        file_path, file_type = QFileDialog.getOpenFileName(self, "选择图片", "./", "All Files (*);;jpg(*.jpg);;png(*.png)")
        file_type = os.path.basename(file_path).split(".")[-1]
        if file_type in ["jpg", "png", "jpeg"]:
            self.img_path = compress_image(file_path)  # 压缩图片
            self.set_img()

    def OnEditName(self):
        self.name_edit.setReadOnly(False)
        self.name_edit.selectAll()
        self.name_edit.setFocus()

    def OnEditNameFinished(self):
        self.name_edit.setReadOnly(True)
        if self.name_edit.text():
            self.name = self.name_edit.text()
        else:
            self.name_edit.setText(self.name)

    def update(self):
        data = get_user_info_post(self.uid)
        if data:
            self.init_status, self.name, self.img_path, self.sex, self.search_accept, self.explain = data
            self.uid_label.setText(" uid: "+self.uid)
            self.img_path = root + img_dir + self.img_path
            self.set_img()
            self.name_edit.setText(self.name)
            self.can_search.setChecked(self.search_accept)
            self.explainEdit.setText(self.explain)
            self.set_check_box()

    def set_img(self):
        if os.path.exists(self.img_path):
            img = QtGui.QPixmap(self.img_path).scaled(self.img_label.width(), self.img_label.height())
            self.img_label.setPixmap(img)

    def set_check_box(self):
        if self.sex == "boy":
            self.boy_rb.setChecked(True)
            self.girl_rb.setChecked(False)
            self.other_rb.setChecked(False)
        elif self.sex == "girl":
            self.boy_rb.setChecked(False)
            self.girl_rb.setChecked(True)
            self.other_rb.setChecked(False)
        else:
            self.boy_rb.setChecked(False)
            self.girl_rb.setChecked(False)
            self.other_rb.setChecked(True)

    def get_check_box(self):
        if self.boy_rb.isChecked():
            self.sex = "boy"
        elif self.girl_rb.isChecked():
            self.sex = "girl"
        else:
            self.sex = "other"
        return self.sex


class UserMainPage(QMainWindow, Ui_UserMainWin):
    switch_login_signal = pyqtSignal()

    def __init__(self):
        super(UserMainPage, self).__init__()
        self.setupUi(self)
        self.setWindowFlags(Qt.FramelessWindowHint)
        self.uid = ""
        self.init_status = False
        self.user_config = {}
        self.new_friend_num = 0
        self.friend_msg_num = 0
        self.group_msg_num = 0

        gw.init()

        self.update_thread = UpdateThread()

        self.friend_win = UserFriendPage()
        self.group_win = UserGroupPage()
        self.me_win = UserMePage()
        self.search_win = UserSearchPage()
        self.new_friend_win = NewFriendPage()
        self.winLayout.addWidget(self.friend_win)
        self.info_win = InfoPage()

        self.friend_button.clicked.connect(lambda: self.OnChangeWidget(self.friend_button.objectName()))
        self.group_button.clicked.connect(lambda: self.OnChangeWidget(self.group_button.objectName()))
        self.me_button.clicked.connect(lambda: self.OnChangeWidget(self.me_button.objectName()))
        self.search_button.clicked.connect(lambda: self.OnChangeWidget(self.search_button.objectName()))
        self.friend_win.read_button.clicked.connect(self.OnFriendRead)
        self.group_win.read_button.clicked.connect(self.OnGroupRead)
        self.group_win.new_button.clicked.connect(self.OnAddGroup)
        self.msg_button.clicked.connect(self.OnMsgWin)
        self.close_button.clicked.connect(self.OnClose)
        self.small_button.clicked.connect(self.OnSmall)
        self.info_button.clicked.connect(self.OnInfo)
        self.update_thread.update_signal.connect(self.update)
        self.update_thread.net_signal.connect(self.change_net_info)
        self.update_thread.remote_landing_signal.connect(self.OnReLogin)
        self.friend_win.msg_num_signal.connect(self.msg_num_update)
        self.group_win.msg_num_signal.connect(self.msg_num_update)
        self.switch_button.clicked.connect(self.OnSwitch)
        self.info_win.sound_signal.connect(self.update_thread.change_loudness)

    def OnInfo(self):
        self.info_win.load_config()
        self.info_win.show()

    def change_net_info(self, info):
        self.net_label.setText(info)

    def OnSwitch(self):
        res = QMessageBox.question(self, u'切换用户', u'是否切换用户？', QMessageBox.Yes | QMessageBox.No)
        if res == QMessageBox.Yes:
            self.info_win.close()
            self.new_friend_win.close()
            gw.clear_dic()
            self.update_thread.terminate()
            self.switch_login_signal.emit()

    def OnReLogin(self):
        self.info_win.close()
        self.update_thread.terminate()
        self.new_friend_win.close()
        gw.clear_dic()
        QMessageBox.warning(self, u'重复登录', u'有人重复登录了此账户!', QMessageBox.Yes)
        self.switch_login_signal.emit()

    def update(self):
        self.user_config = self.LoadConfig()
        self.friend_win.friend_dicts = self.user_config["Friend"]
        self.group_win.group_dicts = self.user_config["Group"]
        self.me_win.uid = self.uid
        self.friend_win.myuid = self.uid
        self.group_win.myuid = self.uid
        self.search_win.myuid = self.uid
        self.new_friend_num = self.user_config["NewFriend"]
        self.friend_win.update()
        self.group_win.update()
        self.me_win.update()
        self.msg_num_update()

    def OnMsgWin(self):
        self.new_friend_num = 0
        change_new_friend_num_post(self.uid, 0)
        self.msg_num_update()
        self.new_friend_win.myuid = self.uid
        self.new_friend_win.update()
        self.new_friend_win.show()

    def OnAddGroup(self):
        name = u"新建群聊" + str(len(self.group_win.group_list))
        add_group_post(self.uid, name)

    def OnFriendRead(self):
        self.friend_msg_num = 0
        self.friend_win.clear_all_msg_num()
        self.msg_num_update()

    def OnGroupRead(self):
        self.group_msg_num = 0
        self.group_win.clear_all_msg_num()
        self.msg_num_update()

    def OnChangeWidget(self, name):
        if name == "friend_button":
            self.winLayout.itemAt(0).widget().setParent(None)
            self.winLayout.addWidget(self.friend_win)
            self.friend_button.setChecked(True)
            self.group_button.setChecked(False)
            self.me_button.setChecked(False)
            self.search_button.setChecked(False)
        elif name == "group_button":
            self.winLayout.itemAt(0).widget().setParent(None)
            self.winLayout.addWidget(self.group_win)
            self.friend_button.setChecked(False)
            self.group_button.setChecked(True)
            self.me_button.setChecked(False)
            self.search_button.setChecked(False)
        elif name == "me_button":
            self.winLayout.itemAt(0).widget().setParent(None)
            self.winLayout.addWidget(self.me_win)
            self.friend_button.setChecked(False)
            self.group_button.setChecked(False)
            self.me_button.setChecked(True)
            self.search_button.setChecked(False)
        elif name == "search_button":
            content = self.search_text.text()
            self.winLayout.itemAt(0).widget().setParent(None)
            self.winLayout.addWidget(self.search_win)
            self.friend_button.setChecked(False)
            self.group_button.setChecked(False)
            self.me_button.setChecked(False)
            self.search_button.setChecked(True)
            if content:
                users, groups = search_post(content)
                self.search_win.user_dicts = users
                self.search_win.group_dicts = groups
                self.search_win.update()

    def LoadConfig(self):
        try:
            status, friend, group, new_friend = get_user_main_post(self.uid)
            self.init_status = status
            return {
                "Friend": friend, "Group": group, "NewFriend": new_friend
            }
        except:
            return {
                "Friend": [], "Group": [], "NewFriend": 0
            }

    def msg_num_update(self):
        self.friend_msg_num = self.friend_win.calc_msg_num()
        self.group_msg_num = self.group_win.calc_msg_num()
        if self.new_friend_num > 0:
            if self.new_friend_num > 99:
                self.new_friend_label.setText("99+")
            else:
                self.new_friend_label.setText(str(self.new_friend_num))
            self.new_friend_label.show()
        else:
            self.new_friend_label.hide()

        if self.friend_msg_num > 0:
            if self.friend_msg_num > 99:
                self.friend_label.setText("99+")
            else:
                self.friend_label.setText(str(self.friend_msg_num))
            self.friend_label.show()
        else:
            self.friend_label.hide()

        if self.group_msg_num > 0:
            if self.group_msg_num > 99:
                self.group_label.setText("99+")
            else:
                self.group_label.setText(str(self.group_msg_num))
            self.group_label.show()
        else:
            self.group_label.hide()

    def OnSmall(self):
        self.showMinimized()

    def OnClose(self):
        res = QMessageBox.question(self, u'确认退出', u'是否退出PyChat？', QMessageBox.Yes | QMessageBox.No)
        if res == QMessageBox.Yes:
            self.info_win.close()
            self.new_friend_win.close()
            gw.clear_dic()
            self.update_thread.terminate()
            self.close()


if __name__ == "__main__":
    root = "../../"
    app = QApplication(sys.argv)
    myWin = UserMainPage()
    myWin.show()
    sys.exit(app.exec_())
